package com.github.jspxnet.worktask.core.node;

import com.github.jspxnet.enums.AuditEnumType;
import com.github.jspxnet.json.JSONObject;
import com.github.jspxnet.utils.BeanUtil;
import com.github.jspxnet.utils.ObjectUtil;
import com.github.jspxnet.utils.RandomUtil;
import com.github.jspxnet.utils.StringUtil;
import com.github.jspxnet.worktask.core.job.*;
import com.github.jspxnet.worktask.model.dto.ProcessResponse;
import com.github.jspxnet.worktask.model.enums.FlowNodeEnumType;
import com.github.jspxnet.worktask.model.enums.JobEnumType;
import com.github.jspxnet.worktask.table.ConfFlowJob;
import com.github.jspxnet.worktask.table.UserFlowLog;
import com.github.jspxnet.worktask.util.WorkFlowUtil;
import java.util.*;

/**
 * 任务类型
 */
public class TaskNodeAction extends BaseNodeAction {
    public final static Map<Integer, Class<?>> TASK_MAP = new HashMap<>();

    static {
        TASK_MAP.put(JobEnumType.NONE.getValue(), NoneJobTask.class);
        TASK_MAP.put(JobEnumType.OR.getValue(), OrJobTask.class);
        TASK_MAP.put(JobEnumType.AND.getValue(), AndJobTask.class);
        TASK_MAP.put(JobEnumType.COPY.getValue(), CopyJobTask.class);
        TASK_MAP.put(JobEnumType.SIGN.getValue(), SignJobTask.class);
        TASK_MAP.put(JobEnumType.SCRIPT.getValue(), ScriptJobTask.class);
        TASK_MAP.put(JobEnumType.HTTP.getValue(), HttpJobTask.class);
        TASK_MAP.put(JobEnumType.CLassJob.getValue(), ClassJobTask.class);
        TASK_MAP.put(JobEnumType.THIRD.getValue(), ThirdJobTask.class);
    }

    @Override
    public ProcessResponse<?> execute() {
        if (StringUtil.isNull(currentWorkTask.getUserFlowId())) {
            currentWorkTask.setUserFlowId(RandomUtil.getRandomGUID(28));
        }

        if (!ObjectUtil.isEmpty(variables)) {
            String varNo = WorkFlowUtil.getVariableNo(currentWorkTask);
            runtimeServiceDAO.putWorkTaskVariable(varNo, new JSONObject(variables));
        }

        //保存留言
        try {
            if (!StringUtil.isNull(workTaskParam.getUserId())) {
                UserFlowLog userFlowLog = BeanUtil.copy(workTaskParam, UserFlowLog.class);
                userFlowLog.setId(0);
                userFlowLog.setUserFlowId(currentWorkTask.getUserFlowId());
                userFlowLog.setPutName(workTaskParam.getUserName());
                userFlowLog.setPutUid(ObjectUtil.toLong(workTaskParam.getUserId()));
                runtimeServiceDAO.save(userFlowLog);
            }
            //直接被驳回

            if (AuditEnumType.NO.getValue() == workTaskParam.getAuditType()) {
                currentWorkTask.setVersion(currentWorkTask.getVersion() + 1);
                currentWorkTask.setFlowNodeType(FlowNodeEnumType.END.getValue());
                runtimeServiceDAO.update(currentWorkTask, new String[]{"version", "flowNodeType"});
                return ProcessResponse.success(currentWorkTask);
                //驳回到开始流程
            }
            //如果已经审核过的直接跳过begin
            boolean isAudited = runtimeServiceDAO.isAudited(currentWorkTask.getFlowNo(),currentWorkTask.getNamespace(),workTaskParam.getDocumentNo(),workTaskParam.getUserId())>0;
            if (isAudited)
            {
                //直接审核通过
                BaseTaskAction baseNodeAction = new NoneJobTask();
                baseNodeAction.setRuntimeServiceDAO(runtimeServiceDAO);
                baseNodeAction.setConfWorkFlowDAO(confWorkFlowDAO);
                baseNodeAction.setUserAdapterDAO(userAdapterDAO);
                baseNodeAction.setCurrentConfFlowNode(currentConfFlowNode);
                baseNodeAction.setCurrentWorkTask(currentWorkTask);
                baseNodeAction.setWorkTaskParam(workTaskParam);
                baseNodeAction.setVariables(variables);
                if (baseNodeAction.execute())
                {
                    inNextNode();
                }
                return ProcessResponse.success(currentWorkTask);
            }

            //如果已经审核过的直接跳过end
            ConfFlowJob confFlowJob = confWorkFlowDAO.getConfFlowJob(currentWorkTask.getFlowNo(), currentWorkTask.getNamespace(), currentWorkTask.getNodeId());
            if (confFlowJob == null) {
                return ProcessResponse.error("任务节点配置为空:" + currentWorkTask.getNodeId());
            }
            //判断权限
            if (!userAdapterDAO.isAuthority(currentConfFlowNode, workTaskParam.getUserId())) {
                return ProcessResponse.error("无权限进行此操作");
            }
            BaseTaskAction baseTaskAction = (BaseTaskAction) TASK_MAP.get(confFlowJob.getJobType()).newInstance();
            baseTaskAction.setRuntimeServiceDAO(runtimeServiceDAO);
            baseTaskAction.setConfWorkFlowDAO(confWorkFlowDAO);
            baseTaskAction.setUserAdapterDAO(userAdapterDAO);
            baseTaskAction.setCurrentConfFlowNode(currentConfFlowNode);
            baseTaskAction.setCurrentWorkTask(currentWorkTask);
            baseTaskAction.setWorkTaskParam(workTaskParam);
            baseTaskAction.setVariables(variables);
            baseTaskAction.setConfFlowJob(confFlowJob);
            if (baseTaskAction.execute())
            {
                inNextNode();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            finishNode();
        }
        return ProcessResponse.success(currentWorkTask);
    }

}
